<template>
	<view>
		<view style="height: 250px;display: flex;flex-direction: column;align-items: end;justify-content: space-evenly">
			<view class="expression">{{currentExpression.replace(/\*/g, '×').replace(/\//g, '÷')}}</view>
			<view class="result">{{currentResult || '0'}}</view>
		</view>

		<view class="buttons-bg" :style="{'height':buttonsHeight + 'px'}">
			<view class="buttons" @click="clearAll">
				<image style="width: 26px;height: 26px;" src="/static/c.png"></image>
			</view>
			<view class="buttons" @click="deleteLast">
				<image style="width: 26px;height: 26px;" src="/static/back.png"></image>
			</view>
			<view class="buttons" @click="toggleHistory">
				<image style="width: 26px;height: 26px;" src="/static/history.png"></image>
			</view>
			<view class="buttons operate" @click="appendOperator('/')">÷</view>

			<view class="buttons" @click="appendNumber('7')">
				<image style="width: 26px;height: 26px;" src="/static/c7.png"></image>
			</view>
			<view class="buttons" @click="appendNumber('8')">
				<image style="width: 26px;height: 26px;" src="/static/c8.png"></image>
			</view>
			<view class="buttons" @click="appendNumber('9')">
				<image style="width: 26px;height: 26px;" src="/static/c9.png"></image>
			</view>
			<view class="buttons operate" @click="appendOperator('*')">×️️</view>

			<view class="buttons" @click="appendNumber('4')">
				<image style="width: 26px;height: 26px;" src="/static/c4.png"></image>
			</view>
			<view class="buttons" @click="appendNumber('5')">
				<image style="width: 26px;height: 26px;" src="/static/c5.png"></image>
			</view>
			<view class="buttons" @click="appendNumber('6')">
				<image style="width: 26px;height: 26px;" src="/static/c6.png"></image>
			</view>
			<view class="buttons operate" @click="appendOperator('-')">－️</view>

			<view class="buttons" @click="appendNumber('1')">
				<image style="width: 26px;height: 26px;" src="/static/c1.png"></image>
			</view>
			<view class="buttons" @click="appendNumber('2')">
				<image style="width: 26px;height: 26px;" src="/static/c2.png"></image>
			</view>
			<view class="buttons" @click="appendNumber('3')">
				<image style="width: 26px;height: 26px;" src="/static/c3.png"></image>
			</view>
			<view class="buttons operate" @click="appendOperator('+')">＋️</view>

			<view class="buttons merged-cell" @click="appendNumber('0')">
				<image style="width: 26px;height: 26px;" src="/static/c0.png"></image>
			</view>
			<view class="buttons" @click="appendDecimal">.</view>
			<view class="buttons equal" @click="calculateResult">=</view>
		</view>
	</view>
</template>

<script setup>
	import {
		ref,
		watch
	} from 'vue'
	import {
		onLoad,
		onShow,
		onReady
	} from '@dcloudio/uni-app'

	const buttonsHeight = ref(0)
	onReady(() => {
		const res = uni.getWindowInfo();
		// console.log('getWindowInfo',res)
		buttonsHeight.value = res.windowHeight - 250
	})

	const currentExpression = ref('');
	const currentResult = ref('');
	const history = ref([]);

	// 运算符优先级
	const operatorPriority = {
		'+': 1,
		'-': 1,
		'*': 2,
		'/': 2
	};

	watch(currentResult, (newVal) => {
		if (newVal && currentExpression.value && newVal !== '错误') {
			history.value.unshift({
				expression: currentExpression.value,
				result: newVal
			});
			if (history.value.length > 20) {
				history.value.pop();
			}
			try {
				uni.setStorageSync('calculateHistory', history.value);
			} catch (e) {
				// error
			}
		}
	});

	const clearAll = () => {
		uni.vibrateShort();
		
		currentExpression.value = '';
		currentResult.value = '';
	};

	const deleteLast = () => {
		uni.vibrateShort();
		
		if (currentResult.value) {
			currentResult.value = '';
		} else {
			currentExpression.value = currentExpression.value.slice(0, -1);
		}
	};

	const toggleHistory = () => {
		uni.vibrateShort();
		
		uni.navigateTo({
			url:"/pages/index/calculate/history"
		})
	};

	const appendNumber = (number) => {
		uni.vibrateShort();
		
		if (currentResult.value) {
			currentExpression.value = '';
			currentResult.value = '';
		}
		currentExpression.value += number;
	};

	const appendOperator = (operator) => {
		uni.vibrateShort();
		
		if (currentResult.value) {
			currentExpression.value = currentResult.value + operator;
			currentResult.value = '';
			return;
		}

		if (!currentExpression.value) {
			if (operator === '-') {
				currentExpression.value += operator;
			}
			return;
		}

		const lastChar = currentExpression.value.slice(-1);

		if (['+', '-', '*', '/'].includes(lastChar)) {
			currentExpression.value = currentExpression.value.slice(0, -1) + operator;
		} else {
			currentExpression.value += operator;
		}
	};

	const appendDecimal = () => {
		uni.vibrateShort();
		
		if (currentResult.value) {
			currentExpression.value = '0.';
			currentResult.value = '';
			return;
		}

		if (!currentExpression.value) {
			currentExpression.value = '0.';
			return;
		}

		const parts = currentExpression.value.split(/[-+*/]/);
		const lastPart = parts[parts.length - 1];

		if (!lastPart.includes('.')) {
			currentExpression.value += '.';
		}
	};

	const toggleSign = () => {
		if (currentResult.value) {
			currentResult.value = currentResult.value.startsWith('-') ?
				currentResult.value.slice(1) :
				'-' + currentResult.value;
			return;
		}

		if (!currentExpression.value) return;

		const regex = /([-+*/]?)(\d+\.?\d*)$/;
		const match = currentExpression.value.match(regex);

		if (match) {
			const [fullMatch, operator, number] = match;

			if (number.startsWith('-')) {
				currentExpression.value = currentExpression.value.replace(
					fullMatch,
					operator + number.slice(1)
				);
			} else {
				currentExpression.value = currentExpression.value.replace(
					fullMatch,
					operator + '-' + number
				);
			}
		}
	};

	// 将中缀表达式转换为后缀表达式（逆波兰式）
	const infixToPostfix = (expression) => {
		const output = [];
		const operators = [];
		let numberBuffer = '';

		for (let i = 0; i < expression.length; i++) {
			const char = expression[i];

			// 如果是数字或小数点，添加到数字缓冲区
			if (!isNaN(char) || char === '.') {
				numberBuffer += char;
			}
			// 如果是运算符
			else if (['+', '-', '*', '/'].includes(char)) {
				// 处理负号的特殊情况（表达式开头或运算符后面的负号）
				if (char === '-' && (i === 0 || ['+', '-', '*', '/'].includes(expression[i - 1]))) {
					numberBuffer += char;
				} else {
					// 将缓冲区中的数字添加到输出
					if (numberBuffer) {
						output.push(parseFloat(numberBuffer));
						numberBuffer = '';
					}

					// 处理运算符优先级
					while (operators.length > 0 &&
						operators[operators.length - 1] !== '(' &&
						operatorPriority[operators[operators.length - 1]] >= operatorPriority[char]) {
						output.push(operators.pop());
					}
					operators.push(char);
				}
			}
			// 如果是左括号
			else if (char === '(') {
				operators.push(char);
			}
			// 如果是右括号
			else if (char === ')') {
				if (numberBuffer) {
					output.push(parseFloat(numberBuffer));
					numberBuffer = '';
				}

				// 弹出运算符直到遇到左括号
				while (operators.length > 0 && operators[operators.length - 1] !== '(') {
					output.push(operators.pop());
				}
				operators.pop(); // 弹出左括号
			}
		}

		// 添加最后一个数字
		if (numberBuffer) {
			output.push(parseFloat(numberBuffer));
		}

		// 弹出剩余的运算符
		while (operators.length > 0) {
			output.push(operators.pop());
		}

		return output;
	};

	// 计算后缀表达式
	const calculatePostfix = (postfix) => {
		const stack = [];

		for (const token of postfix) {
			// 如果是数字，压入栈
			if (typeof token === 'number') {
				stack.push(token);
			}
			// 如果是运算符，弹出两个数字进行计算
			else {
				if (stack.length < 2) {
					throw new Error('无效的表达式');
				}

				const b = stack.pop();
				const a = stack.pop();
				let result;

				switch (token) {
					case '+':
						result = a + b;
						break;
					case '-':
						result = a - b;
						break;
					case '*':
						result = a * b;
						break;
					case '/':
						if (b === 0) {
							throw new Error('除数不能为零');
						}
						result = a / b;
						break;
					default:
						throw new Error('未知运算符');
				}

				stack.push(result);
			}
		}

		if (stack.length !== 1) {
			throw new Error('无效的表达式');
		}

		return stack[0];
	};

	// 计算结果（不使用eval）
	const calculateResult = () => {
		uni.vibrateShort();
		
		if (!currentExpression.value) return;

		try {
			// 替换用户友好的运算符为JavaScript可识别的运算符
			const expression = currentExpression.value.replace('×', '*').replace('÷', '/');

			// 将中缀表达式转换为后缀表达式
			const postfix = infixToPostfix(expression);

			// 计算后缀表达式
			const result = calculatePostfix(postfix);

			// 处理结果显示，避免过多小数位
			currentResult.value = Number.isInteger(result) ?
				result.toString() :
				result.toFixed(6).replace(/0+$/, '').replace(/\.$/, '');
				// console.log('currentResult.value',currentResult.value)
		} catch (error) {
			currentResult.value = '错误';
			console.error('计算错误:', error.message);
		}
	};
</script>

<style>
	@import 'calculate.css'
</style>